package com.gitee.zzh.sqllineage.transform;

import com.gitee.zzh.sqllineage.util.ColumnInfoUtils;
import com.gitee.zzh.sqllineage.vo.TransformVO;

import java.util.List;
import java.util.Map;
import java.util.Set;

public class ReplaceStarFields extends ColumnInfoUtils {
    private static final String S1 = "SELECT * FROM ";
    private static final String S2 = ",* FROM ";
    private static final String S3 = "SELECT *,";
    private static final String S4 = ".* FROM ";
    private static final String S5 = ".*,";

    public static String getReplacedStarText(TransformVO transformVO) {
        String text = transformVO.getText();
        if(isBlank(text)) {
            return null;
        }
        while (hasStarExpression(text)) {
            String[] textArr = text.split(";");
            for (String textSql : textArr) {
                if(!hasStarExpression(textSql)) {
                    continue;
                }
                List<String> unienSelectList = getUnienSelectList(textSql, false);
                for (String textPart : unienSelectList) {
                    textPart = textPart.trim();
                    if(textPart.contains(S1)) {
                        String tableName = textPart.substring(textPart.indexOf(S1) + S1.length());
                        transformVO.setText(text);
                        String appendedColumns = getColumnFields(transformVO, tableName);
                        if(isBlank(appendedColumns)) {
                            continue;
                        }
                        text = text.replace(S1 + tableName, "," + appendedColumns + " FROM " + tableName);
                    }
                    if(textPart.contains(S2)) {
                        String tableName = textPart.substring(textPart.indexOf(S2) + S2.length());
                        transformVO.setText(text);
                        String appendedColumns = getColumnFields(transformVO, tableName);
                        if(isBlank(appendedColumns)) {
                            continue;
                        }
                        text = text.replace(S2 + tableName, "," + appendedColumns + " FROM " + tableName);
                    }
                    if(textPart.contains(S3) && textPart.contains(" FROM ")) {
                        String right = textPart.substring(textPart.indexOf(S3) + S3.length());
                        if(!right.contains(" FROM ")) {
                            continue;
                        }
                        String tableName = right.substring(right.indexOf(" FROM ") + " FROM ".length());
                        transformVO.setText(text);
                        String appendedColumns = getColumnFields(transformVO, tableName);
                        if(isBlank(appendedColumns)) {
                            continue;
                        }
                        text = text.replace(S3 + right, "SELECT " + appendedColumns + "," + right);
                    }
                    if(textPart.contains(S4) && textPart.contains(" FROM ")) {
                        String left = textPart.substring(0, textPart.indexOf(S4));
                        String right = textPart.substring(textPart.indexOf(S4) + S4.length());
                        String alias = substringByLastSymbol(left, " ", ",");
                        transformVO.setText(text);
                        String aliasColumnFields = getAliasColumnFields(alias, right, textPart, transformVO);
                        if(isBlank(aliasColumnFields)) {
                            continue;
                        }
                        text = text.replace(left + S4 + right, left.substring(0, left.length() - alias.length()) + aliasColumnFields + " FROM " + right);
                    }
                    if(textPart.contains(S5)) {
                        String left = textPart.substring(0, textPart.indexOf(S5));
                        String right = textPart.substring(textPart.indexOf(S5) + S5.length());
                        String alias = substringByLastSymbol(left, " ", ",");
                        transformVO.setText(text);
                        String aliasColumnFields = getAliasColumnFields(alias, right, textPart, transformVO);
                        if(isBlank(aliasColumnFields)) {
                            continue;
                        }
                        text = text.replace(left + S5 + right, left.substring(0, left.length() - alias.length()) + aliasColumnFields + "," + right);
                    }
                }
            }
        }
        return text;
    }

    public static String getColumnFields(TransformVO transformVO, String tableName) {
        tableName = substringBySymbol(tableName, " ", "(", ")");
        tableName = substringByLastSymbol(tableName, ".");
        List<Map<String, String>> columns = getColumnsInfo(transformVO, tableName);
        return getColumns(columns);
    }

    public static String getAliasColumnFields(String alias, String right, String textPart, TransformVO transformVO) {
        alias = substringByLastSymbol(alias, ",");
        Set<String> tableSet = getTableBySelect(right);
        String tableName = "";
        for (String tableName1 : tableSet) {
            if(contains(textPart, tableName1 + " " + alias, " ", ")", ",") || contains(textPart, tableName1 + " AS " + alias, " ", ")", ",")) {
                tableName = tableName1;
                break;
            }
        }
        if("".equals(tableName)) {
            return null;
        }
        List<Map<String, String>> columns = ColumnInfoUtils.getColumnsInfo(transformVO, tableName);
        return getColumns(columns);
    }

    public static String getInsertColumns(TransformVO transformVO, String sqlText, String creatAsSqlText) {
        String text = transformVO.getText();
        String tableNameTemp = transformVO.getTableNameTemp();
        String insertSqlColumns;
        if(sqlText.equals(creatAsSqlText)) {
            List<Map<String, String>> columns = getColumnsInfoByCreateAsText(text, tableNameTemp);
            insertSqlColumns = getColumns(columns);
            if(insertSqlColumns != null) {
                return insertSqlColumns;
            }
        }
        if(sqlText.startsWith("INSERT INTO " + tableNameTemp + "(") || sqlText.startsWith("INSERT INTO " + tableNameTemp + " (")) {
            insertSqlColumns = sqlText.substring(sqlText.indexOf("(") + "(".length(), sqlText.indexOf(")"));
            return insertSqlColumns;
        }
        if(sqlText.startsWith("INSERT INTO " + tableNameTemp + " SELECT ")) {
            List<Map<String, String>> columns = ColumnInfoUtils.getColumnsInfo(transformVO, tableNameTemp);
            insertSqlColumns = getColumns(columns);
            if(insertSqlColumns != null) {
                return insertSqlColumns;
            }
            String selectColumns = sqlText.substring(sqlText.indexOf(" SELECT ") + " SELECT ".length(), sqlText.indexOf(" FROM "));
            return getInsertFields(selectColumns);
        }
        return null;
    }
}
